package com.codegen.generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.io.FileWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.*;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.sql.Statement;
import java.sql.SQLException;

/**
 * MyBatis-Plus代码生成器配置
 * 用于生成包含Javadoc注释的实体类、Mapper、Service和Controller
 */
@Slf4j
@Service
public class CodeGenerator {
    // 1. 定义常量
    private static final String COLUMN_NAME = "COLUMN_NAME";
    private static final String LOG_PK_FIELD = "表 {} 的主键字段: {}";
    private static final String LOG_PK_ERROR = "获取表主键信息失败：{}";
    private static final String JAVA_STRING = "String";
    private static final String JAVA_INTEGER = "Integer";
    private static final String JAVA_LOCALDATETIME = "LocalDateTime";
    private static final String[] TABLE_PREFIX = {"tbl_", "t_", "sys_" , "hr_" , "nfint_" , "nfinm_" };

    /**
     * 代码生成入口，供Controller调用
     */
    public void generate(String url, String username, String password,
                         String parentPackage, String author, String outputDir,
                         List<String> tables) {
        try {
            log.info("开始生成代码...");
            log.info("数据库URL: {}" , url);
            log.info("用户名: {}" , username);
            log.info("输出目录: {}" , outputDir);
            log.info("包名: {}" , parentPackage);
            log.info("作者: {}" , author);
            log.info("表名: {}" , tables);

            // 确保输出目录存在
            Path outputPath = Paths.get(outputDir);
            Files.createDirectories(outputPath);
            log.info("输出目录已创建: {}" , outputPath.toAbsolutePath());

            // 创建mapper输出目录
            Path mapperPath = Paths.get(outputDir, "mapper");
            Files.createDirectories(mapperPath);
            log.info("Mapper目录已创建: {}" , mapperPath.toAbsolutePath());
            
            // 获取模板文件的绝对路径
            String projectDir = System.getProperty("user.dir");
            String templatesDir = projectDir + "/src/main/resources/templates/";
            log.info("模板目录: {}" , templatesDir);
            
            // 检查模板文件是否存在

            // 使用最简单的配置，不指定自定义模板，先确保基本功能正常
            FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author(author)
                        .enableSwagger() // 开启 swagger 模式
                        .outputDir(outputDir)
                        .disableOpenDir();
                    log.info("全局配置已设置");
                })
                .packageConfig(builder -> {
                    builder.parent(parentPackage)
                        .pathInfo(Collections.singletonMap(OutputFile.xml, outputDir + "/mapper"));
                    log.info("包配置已设置");
                })
                .strategyConfig(builder -> {
                    builder.addInclude(tables)
                           .addTablePrefix(TABLE_PREFIX) // 设置过滤表前缀
                        .entityBuilder()
                            .enableFileOverride()
                            .javaTemplate("templates/entity.java")
                            .enableLombok()
                            .enableTableFieldAnnotation() // 启用@TableField注解
                            .fieldUseJavaDoc(true)
                        .controllerBuilder()
                            .enableFileOverride()
                            .enableRestStyle()
                            .formatFileName("%sController")
                            .template("templates/controller.java")
                        .serviceBuilder()
                            .enableFileOverride()
                            .serviceTemplate("templates/service.java")
                            .serviceImplTemplate("templates/serviceImpl.java")
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                        .mapperBuilder()
                            .enableFileOverride()
                            .enableBaseResultMap()
                            .enableBaseColumnList()
                            .mapperTemplate("templates/mapper.java")
                            .formatMapperFileName("%sMapper")
                            .formatXmlFileName("%sMapper");
                    log.info("策略配置已设置");
                })
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
            for (String table : tables) {
                // 生成请求实体类
                generateRequestEntities(url,username, password, author, table,
                        parentPackage, outputDir);
            }

            log.info("代码生成完成");
        } catch (Exception e) {
            log.error("代码生成失败: {}" , e.getMessage());
            throw new CodeGenException("代码生成失败: " + e.getMessage(), e);
        }
    }


    /**
     * 生成请求实体类
     * @param tableName 表名
     * @param packageName 包名
     * @param author 作者
     * @param outputDir 输出目录
     */
    private void generateRequestEntities(String url, String username, String password,
                                         String author, String tableName, String packageName, String outputDir) {
        try {
            // 获取实体类名
            String entityName = NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(tableName.replaceAll("^(t_|sys_|hr_|nfint_|nfinm_)", "")));

            // 创建输出目录
            String packagePath = (packageName + ".entity.request").replace(".", "/");
            File dir = new File(outputDir + File.separator + packagePath);
            if (!dir.exists() && !dir.mkdirs()) {
                    throw new CodeGenException("无法创建目录: " + dir.getAbsolutePath());
                }


            // 使用FreeMarker模板引擎生成请求实体类
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
            cfg.setClassLoaderForTemplateLoading(getClass().getClassLoader(), "templates");
            cfg.setDefaultEncoding("UTF-8");

            // 获取表的字段信息
            List<TableField> fields = getTableFields(url, username, password, tableName);
            log.info("获取到表 {} 的字段数量: {}", tableName, fields.size());

            // 准备数据模型
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("packageEntity", packageName + ".entity");
            dataModel.put("entity", entityName);
            dataModel.put("tableComment", getTableComment(tableName));
            dataModel.put("author", author);
            dataModel.put("date", new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date()));
            dataModel.put("swagger", true);
            // 将表字段信息添加到数据模型中
            Map<String, Object> tableInfo = new HashMap<>();
            tableInfo.put("fields", fields);
            dataModel.put("table", tableInfo);

            // 打印数据模型，用于调试
            log.info("数据模型: {}", dataModel);

            // 生成分页查询请求
            generateFromTemplate(cfg, "page-request.java.ftl", dataModel, dir, "Find" + entityName + "ByPageReq.java");

            // 生成列表查询请求
            generateFromTemplate(cfg, "list-request.java.ftl", dataModel, dir, "Find" + entityName + "ListReq.java");

            // 生成详情查询请求
            generateFromTemplate(cfg, "detail-request.java.ftl", dataModel, dir, "Find" + entityName + "DetailReq.java");

            // 生成删除请求
            generateFromTemplate(cfg, "delete-request.java.ftl", dataModel, dir, "Del" + entityName + "Req.java");

            // 生成批量删除请求
            generateFromTemplate(cfg, "batch-delete-request.java.ftl", dataModel, dir, "BatchDelete" + entityName + "Req.java");

        } catch (Exception e) {
            log.error("生成请求实体类失败", e);
        }
    }

    /**
     * 获取表的字段信息
     * @param tableName 表名
     * @return 字段列表
     */
    private List<TableField> getTableFields(String url, String username, String password, String tableName) {
        try {
            log.info("开始获取表 {} 的字段信息", tableName);

            // 获取主键信息
            Set<String> primaryKeys = getPrimaryKeys(url, username, password, tableName);
            log.info("获取到表 {} 的主键字段数量: {}", tableName, primaryKeys.size());

            // 获取表字段信息
            List<TableField> fields = getFieldsByMetaData(url, username, password, tableName, primaryKeys);
            log.info("使用 DatabaseMetaData 获取到表 {} 的字段数量: {}", tableName, fields.size());

            // 如果没有获取到字段，尝试使用 SQL 查询
            if (fields.isEmpty()) {
                log.info("尝试使用 SQL 查询获取表字段信息");
                fields = getFieldsBySQL(url, username, password, tableName, primaryKeys);
            }

            // 如果仍然没有获取到字段，添加一些模拟字段用于测试
            if (fields.isEmpty()) {
                log.warn("未能获取到表 {} 的字段信息，添加模拟字段用于测试", tableName);
                fields = addMockFieldsIfEmpty(tableName);
            }

            // 确保至少有一个主键字段
            boolean hasPrimaryKey = fields.stream().anyMatch(TableField::isKeyFlag);
            if (!hasPrimaryKey && !fields.isEmpty()) {
                // 如果没有主键字段，将第一个字段设置为主键
                TableField firstField = fields.get(0);
                firstField.setKeyFlag(true);
                log.warn("未找到表 {} 的主键字段，将字段 {} 设置为主键", tableName, firstField.getName());
            }

            return fields;
        } catch (Exception e) {
            log.error("获取表字段信息失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取主键信息
     * @param tableName 表名
     * @return 主键集合
     */
    private Set<String> getPrimaryKeys(String url, String username, String password, String tableName) {
        Set<String> primaryKeys = new HashSet<>();

        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            log.info("正在获取表 {} 的主键信息", tableName);

            // 首先获取主键信息
            DatabaseMetaData metaData = conn.getMetaData();
            getPrimaryKeysByMetaData(metaData, tableName, primaryKeys);

            // 如果没有找到主键，尝试使用不同的表名大小写
            if (primaryKeys.isEmpty()) {
                getPrimaryKeysByMetaData(metaData, tableName.toUpperCase(), primaryKeys);
            }

            // 如果仍然没有找到主键，尝试使用小写表名
            if (primaryKeys.isEmpty()) {
                getPrimaryKeysByMetaData(metaData, tableName.toLowerCase(), primaryKeys);
            }

            // 如果仍然没有找到主键，假设 id 字段是主键
            if (primaryKeys.isEmpty()) {
                primaryKeys.add("id");
                log.warn("未找到表 {} 的主键信息，假设 id 字段是主键", tableName);
            }
        } catch (Exception e) {
            log.error(LOG_PK_ERROR, e.getMessage());
        }

        return primaryKeys;
    }

    /**
     * 新增方法
     */
    private void getPrimaryKeysByMetaData(DatabaseMetaData metaData, String tableName, Set<String> primaryKeys) {
        try {
            ResultSet pkRs = metaData.getPrimaryKeys(null, null, tableName);
            while (pkRs.next()) {
                String columnName = pkRs.getString(COLUMN_NAME);
                primaryKeys.add(columnName);
                log.info(LOG_PK_FIELD, tableName, columnName);
            }
            pkRs.close();
        } catch (Exception e) {
            log.error(LOG_PK_ERROR, e.getMessage());
        }
    }

    /**
     * 获取表字段信息
     * @param tableName 表名
     * @param primaryKeys 主键集合
     * @return 字段列表
     */
    private List<TableField> getFieldsByMetaData(String url, String username, String password, String tableName, Set<String> primaryKeys) {
        List<TableField> fields = new ArrayList<>();

        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            log.info("正在获取表 {} 的字段信息", tableName);

            // 尝试使用 DatabaseMetaData 获取表字段信息
            DatabaseMetaData metaData = conn.getMetaData();
            ResultSet rs = metaData.getColumns(null, null, tableName, null);

            int fieldCount = 0;
            while (rs.next()) {
                fieldCount++;
                String columnName = rs.getString(COLUMN_NAME);
                String columnType = rs.getString("TYPE_NAME");
                String columnComment = rs.getString("REMARKS");

                log.info("字段信息: 名称={}, 类型={}, 注释={}, 是否主键={}",
                        columnName, columnType, columnComment, primaryKeys.contains(columnName));

                TableField field = new TableField();
                field.setName(columnName);
                field.setType(getJavaType(columnType));
                field.setComment(columnComment != null ? columnComment : "");
                field.setPropertyName(NamingStrategy.underlineToCamel(columnName));
                field.setPropertyType(getJavaType(columnType));
                field.setCapitalName(NamingStrategy.capitalFirst(field.getPropertyName()));
                field.setKeyFlag(primaryKeys.contains(columnName));

                fields.add(field);
            }

            log.info("使用 DatabaseMetaData 获取到表 {} 的字段数量: {}", tableName, fieldCount);
        } catch (Exception e) {
            log.error("获取表字段信息失败", e);
        }

        return fields;
    }

    /**
     * 获取表字段信息
     * @param tableName 表名
     * @param primaryKeys 主键集合
     * @return 字段列表
     */
    private List<TableField> getFieldsBySQL(String url, String username, String password, String tableName, Set<String> primaryKeys) {
        List<TableField> fields = new ArrayList<>();
        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            log.info("尝试使用 SQL 查询获取表字段信息");
            String[] sqlQueries = {
                "SHOW COLUMNS FROM " + tableName,
                "SHOW COLUMNS FROM `" + tableName + "`",
                "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, COLUMN_KEY FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + tableName + "'",
                "SELECT COLUMN_NAME, DATA_TYPE, COMMENTS, CONSTRAINT_TYPE FROM USER_TAB_COLUMNS LEFT JOIN USER_CONS_COLUMNS ON USER_TAB_COLUMNS.TABLE_NAME = USER_CONS_COLUMNS.TABLE_NAME AND USER_TAB_COLUMNS.COLUMN_NAME = USER_CONS_COLUMNS.COLUMN_NAME LEFT JOIN USER_CONSTRAINTS ON USER_CONS_COLUMNS.CONSTRAINT_NAME = USER_CONSTRAINTS.CONSTRAINT_NAME WHERE USER_TAB_COLUMNS.TABLE_NAME = '" + tableName.toUpperCase() + "' AND CONSTRAINT_TYPE = 'P'",
                "SELECT name, type, '' as comment FROM pragma_table_info('" + tableName + "')"
            };
            Statement stmt = conn.createStatement();
            for (String sql : sqlQueries) {
                stmt.addBatch(sql);
            }
            int idx = 0;
            boolean hasResults = stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT);
            while (hasResults || stmt.getUpdateCount() != -1) {
                ResultSet rs = stmt.getResultSet();
                if (rs != null) {
                    fields = parseFieldsFromResultSet(rs, sqlQueries[idx], primaryKeys);
                    if (!fields.isEmpty()) {
                        log.info("使用 SQL 查询获取到表 {} 的字段数量: {}", tableName, fields.size());
                        break;
                    }
                    rs.close();
                }
                idx++;
                hasResults = stmt.getMoreResults(Statement.KEEP_CURRENT_RESULT);
            }
        } catch (Exception e) {
            log.error("执行 SQL 查询失败", e);
        }
        return fields;
    }

    private List<TableField> parseFieldsFromResultSet(ResultSet rs, String sql, Set<String> primaryKeys) throws SQLException {
        if (sql.startsWith("SHOW COLUMNS")) {
            return parseFieldsFromShowColumns(rs, primaryKeys);
        } else if (sql.contains("INFORMATION_SCHEMA.COLUMNS")) {
            return parseFieldsFromInformationSchema(rs, primaryKeys);
        } else if (sql.contains("USER_TAB_COLUMNS")) {
            return parseFieldsFromUserTabColumns(rs, primaryKeys);
        } else if (sql.contains("pragma_table_info")) {
            return parseFieldsFromPragma(rs, primaryKeys);
        }
        return Collections.emptyList();
    }

    private List<TableField> parseFieldsFromShowColumns(ResultSet rs, Set<String> primaryKeys) throws SQLException {
        List<TableField> fields = new ArrayList<>();
        while (rs.next()) {
            String columnName = rs.getString("Field");
            String columnType = rs.getString("Type");
            String columnKey = rs.getString("Key");
            boolean isPrimaryKey = "PRI".equals(columnKey) || primaryKeys.contains(columnName);
            fields.add(buildTableField(columnName, columnType, "", isPrimaryKey));
        }
        return fields;
    }

    private List<TableField> parseFieldsFromInformationSchema(ResultSet rs, Set<String> primaryKeys) throws SQLException {
        List<TableField> fields = new ArrayList<>();
        while (rs.next()) {
            String columnName = rs.getString(COLUMN_NAME);
            String columnType = rs.getString("DATA_TYPE");
            String columnComment = rs.getString("COLUMN_COMMENT");
            String columnKey = rs.getString("COLUMN_KEY");
            boolean isPrimaryKey = "PRI".equals(columnKey) || primaryKeys.contains(columnName);
            fields.add(buildTableField(columnName, columnType, columnComment, isPrimaryKey));
        }
        return fields;
    }

    private List<TableField> parseFieldsFromUserTabColumns(ResultSet rs, Set<String> primaryKeys) throws SQLException {
        List<TableField> fields = new ArrayList<>();
        while (rs.next()) {
            String columnName = rs.getString(COLUMN_NAME);
            String columnType = rs.getString("DATA_TYPE");
            String columnComment = rs.getString("COMMENTS");
            String constraintType = rs.getString("CONSTRAINT_TYPE");
            boolean isPrimaryKey = "P".equals(constraintType) || primaryKeys.contains(columnName);
            fields.add(buildTableField(columnName, columnType, columnComment, isPrimaryKey));
        }
        return fields;
    }

    private List<TableField> parseFieldsFromPragma(ResultSet rs, Set<String> primaryKeys) throws SQLException {
        List<TableField> fields = new ArrayList<>();
        while (rs.next()) {
            String columnName = rs.getString("name");
            String columnType = rs.getString("type");
            boolean isPrimaryKey = primaryKeys.contains(columnName);
            fields.add(buildTableField(columnName, columnType, "", isPrimaryKey));
        }
        return fields;
    }

    private TableField buildTableField(String columnName, String columnType, String columnComment, boolean isPrimaryKey) {
        TableField field = new TableField();
        field.setName(columnName);
        field.setType(getJavaType(columnType));
        field.setComment(columnComment != null ? columnComment : "");
        field.setPropertyName(NamingStrategy.underlineToCamel(columnName));
        field.setPropertyType(getJavaType(columnType));
        field.setCapitalName(NamingStrategy.capitalFirst(field.getPropertyName()));
        field.setKeyFlag(isPrimaryKey);
        // 新增属性赋值
        field.setAnnotationColumnName(columnName); // 保持原始数据库字段名
        field.setConvert(!NamingStrategy.underlineToCamel(columnName).equals(columnName)); // 需要转换时为true
        // 其他属性如fill、versionField、logicDeleteField可根据实际需求后续完善
        return field;
    }

    /**
     * 添加一些模拟字段
     * @param tableName 表名
     * @return 字段列表
     */
    private List<TableField> addMockFieldsIfEmpty(String tableName) {
        log.warn("未能获取到表 {} 的字段信息，添加模拟字段用于测试", tableName);

        // 添加一些模拟字段
        TableField field1 = new TableField();
        field1.setName("id");
        field1.setType("Long");
        field1.setComment("主键ID");
        field1.setPropertyName("id");
        field1.setPropertyType(JAVA_INTEGER);
        field1.setCapitalName("Id");
        field1.setKeyFlag(true);  // 设置为主键
        List<TableField> fields = new ArrayList<>();
        fields.add(field1);

        TableField field2 = new TableField();
        field2.setName("name");
        field2.setType(JAVA_STRING);
        field2.setComment("名称");
        field2.setPropertyName("name");
        field2.setPropertyType(JAVA_STRING);
        field2.setCapitalName("Name");
        field2.setKeyFlag(false);
        fields.add(field2);

        TableField field3 = new TableField();
        field3.setName("code");
        field3.setType(JAVA_STRING);
        field3.setComment("编码");
        field3.setPropertyName("code");
        field3.setPropertyType(JAVA_STRING);
        field3.setCapitalName("Code");
        field3.setKeyFlag(false);
        fields.add(field3);

        TableField field4 = new TableField();
        field4.setName("description");
        field4.setType(JAVA_STRING);
        field4.setComment("描述");
        field4.setPropertyName("description");
        field4.setPropertyType(JAVA_STRING);
        field4.setCapitalName("Description");
        field4.setKeyFlag(false);
        fields.add(field4);

        TableField field5 = new TableField();
        field5.setName("status");
        field5.setType(JAVA_INTEGER);
        field5.setComment("状态");
        field5.setPropertyName("status");
        field5.setPropertyType(JAVA_INTEGER);
        field5.setCapitalName("Status");
        field5.setKeyFlag(false);
        fields.add(field5);

        TableField field6 = new TableField();
        field6.setName("create_time");
        field6.setType(JAVA_LOCALDATETIME);
        field6.setComment("创建时间");
        field6.setPropertyName("createTime");
        field6.setPropertyType(JAVA_LOCALDATETIME);
        field6.setCapitalName("CreateTime");
        field6.setKeyFlag(false);
        fields.add(field6);

        return fields;
    }

    /**
     * 获取Java类型
     * @param dbType 数据库类型
     * @return Java类型
     */
    private String getJavaType(String dbType) {
        dbType = dbType.toUpperCase();
        return switch (dbType) {
            case "VARCHAR", "CHAR", "TEXT" -> JAVA_STRING;
            case "INT", "INTEGER", "TINYINT", "SMALLINT" -> JAVA_INTEGER;
            case "BIGINT" -> "Long";
            case "DECIMAL", "NUMERIC" -> "java.math.BigDecimal";
            case "FLOAT" -> "Float";
            case "DOUBLE" -> "Double";
            case "DATE" -> "LocalDate";
            case "DATETIME", "TIMESTAMP" -> JAVA_LOCALDATETIME;
            case "BIT", "BOOLEAN" -> "Boolean";
            default -> JAVA_STRING;
        };
    }

    /**
     * 表字段信息
     */
    @Setter
    @Getter
    public static class TableField {
        // Getters and setters
        private String name;
        private String type;
        private String comment;
        private String propertyName;
        private String propertyType;
        private String capitalName;
        private boolean keyFlag;  // 是否为主键
        private String annotationColumnName; // 数据库字段名
        private boolean convert; // 是否需要转换
        private String fill; // 填充策略
        private boolean versionField; // 乐观锁
        private boolean logicDeleteField; // 逻辑删除

        @Override
        public String toString() {
            return "TableField{" +
                    "name='" + name + '\'' +
                    ", type='" + type + '\'' +
                    ", comment='" + comment + '\'' +
                    ", propertyName='" + propertyName + '\'' +
                    ", propertyType='" + propertyType + '\'' +
                    ", capitalName='" + capitalName + '\'' +
                    ", keyFlag=" + keyFlag +
                    ", annotationColumnName='" + annotationColumnName + '\'' +
                    ", convert=" + convert +
                    ", fill='" + fill + '\'' +
                    ", versionField=" + versionField +
                    ", logicDeleteField=" + logicDeleteField +
                    '}';
        }
    }

    /**
     * 从模板生成文件
     * @param cfg FreeMarker配置
     * @param templateName 模板名称
     * @param dataModel 数据模型
     * @param dir 输出目录
     * @param fileName 文件名
     */
    @SuppressWarnings("unchecked")
    private void generateFromTemplate(Configuration cfg, String templateName, Map<String, Object> dataModel, File dir, String fileName) {
        try {
            log.info("开始生成文件: {}", fileName);

            // 检查数据模型中的表字段信息
            Map<String, Object> tableInfo = (Map<String, Object>) dataModel.get("table");
            if (tableInfo != null) {
                List<TableField> fields = (List<TableField>) tableInfo.get("fields");
                if (fields != null) {
                    log.info("数据模型中的表字段数量: {}", fields.size());
                    for (TableField field : fields) {
                        log.info("字段信息: 名称={}, 属性名={}, 类型={}, 注释={}",
                                field.getName(), field.getPropertyName(), field.getPropertyType(), field.getComment());
                    }
                } else {
                    log.warn("数据模型中的表字段列表为空");
                }
            } else {
                log.warn("数据模型中没有表信息");
            }

            // 获取模板
            Template template = cfg.getTemplate(templateName);

            // 创建输出文件
            File outputFile = new File(dir, fileName);

            // 生成文件
            try (Writer writer = new FileWriter(outputFile)) {
                template.process(dataModel, writer);
            }

            log.info("生成请求实体类成功: {}", outputFile.getAbsolutePath());
        } catch (Exception e) {
            log.error("生成请求实体类失败: " + fileName, e);
        }
    }

    /**
     * 获取表注释
     * @param tableName 表名
     * @return 表注释
     */
    private String getTableComment(String tableName) {
        // 这里简化处理，实际应该从数据库中获取表注释
        return tableName.replaceAll("^(t_|sys_|hr_|nfint_|nfinm_)", "") + "表";
    }
}
